﻿ //-----------------------------------------------------------------------
// <copyright file="TrayIconCreator.cs" company="Redmist">
//     Copyright (c) Damien T Smith. All rights reserved.
// </copyright>
// <author>Damien Smith</author>
//-----------------------------------------------------------------------

namespace Redmist.UsageMonitor.IconCreation
{
    using System;
    using System.Drawing;
    using Redmist.UsageMonitor.CustomControls;

    /// <summary>Contains methods used for creating a tray icon which shows usage and status.</summary>
    public class TrayIconCreator
    {
        /// <summary>Represents the Argb value for the green status color.</summary>
        private const int GreenStatusArgb = -16718336;

        /// <summary>Represents the Argb value for the red status color.</summary>
        private const int RedStatusRgb = -65536;

        /// <summary>Represents the Argb value for the yellow status color.</summary>
        private const int YellowStatusRgb = -256;

        /// <summary>A System.Drawing.Bitmap representing the drawing object for the icon.</summary>
        private Bitmap bitmap;

        /// <summary>The percent value to draw on the icon.</summary>
        private int percentValue;

        /// <summary>A System.Drawing.Color representing color of the status bar on the icon.</summary>
        private Color statusColor;

        /// <summary>A System.Drawing.Color representing background color of the icon.</summary>
        private Color backColor;

        /// <summary>A System.Drawing.Color representing color of the text on the icon.</summary>
        private Color textColor;

        /// <summary>A System.Drawing.Color representing color of the text shadow on the icon.</summary>
        private Color shadowColor;

        /// <summary>A value indicating whether ClearType should be used when drawing the percentage text.</summary>
        private bool clearType;

        /// <summary>A value indicating whether a solid background should drawn on the icon.</summary>
        private bool background;

        /// <summary>A value indicating whether a shadow should drawn for the percentage text.</summary>
        private bool textShadow;

        /// <summary>Initializes a new instance of the TrayIconCreator class.</summary>
        /// <param name="bitmap">A System.Drawing.Bitmap representing the drawing object for the icon.</param>
        /// <param name="percentValue">The percent value to draw on the icon.</param>
        /// <param name="statusColor">A System.Drawing.Color representing color of the status bar on the icon.</param>
        /// <param name="backColor">A System.Drawing.Color representing background color of the icon.</param>
        /// <param name="textColor">A System.Drawing.Color representing color of the text on the icon.</param>
        /// <param name="shadowColor">A System.Drawing.Color representing color of the text shadow on the icon.</param>
        /// <param name="clearType">A value indicating whether ClearType should be used when drawing the percentage text.</param>
        /// <param name="background">A value indicating whether a solid background should drawn on the icon.</param>
        /// <param name="textShadow">A value indicating whether a shadow should drawn for the percentage text.</param>
        public TrayIconCreator(Bitmap bitmap, int percentValue, Color statusColor, Color backColor, Color textColor, Color shadowColor, bool clearType, bool background, bool textShadow)
        {
            this.bitmap = bitmap;
            this.percentValue = percentValue;
            this.statusColor = statusColor;
            this.backColor = backColor;
            this.textColor = textColor;
            this.shadowColor = shadowColor;
            this.clearType = clearType;
            this.background = background;
            this.textShadow = textShadow;
        }

        /// <summary>Fills the interior of a rectangle specified by a System.Drawing.Rectangle structure.</summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing the drawing surface.</param>
        /// <param name="brush">A System.Drawing.Brush representing the fill brush.</param>
        /// <param name="rectangle">A System.Drawing.Rectangle representing the area to be filled.</param>
        public static void DrawBackgroundArea(IGraphics graphics, Brush brush, Rectangle rectangle)
        {
            graphics.FillRectangle(brush, rectangle);
        }

        /// <summary>
        /// Draws the specified text string in the specified rectangle with the specified System.Drawing.Brush
        /// and System.Drawing.Font objects using the formatting attributes of the specified System.Drawing.StringFormat.
        /// </summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing the drawing surface.</param>
        /// <param name="text">A System.String representing the text to be drawn.</param>
        /// <param name="font">A System.Drawing.Font representing the font to be used.</param>
        /// <param name="brush">A System.Drawing.Brush representing the brush to be used to draw the text.</param>
        /// <param name="centerPoint">A System.Drawing.PointF representing the text center area.</param>
        /// <param name="format">A System.Drawing.StringFormat representing the format for the text.</param>
        public static void DrawPercentageText(IGraphics graphics, string text, Font font, Brush brush, PointF centerPoint, StringFormat format)
        {
            graphics.DrawString(text, font, brush, centerPoint, format);
        }

        /// <summary>Translates a progress status color into an icon status bar color.</summary>
        /// <param name="progressStatusColor">A Redmist.UsageMonitor.CustomControls.ProgressStatusColor representing a progress status color.</param>
        /// <returns>A System.Drawing.Color representing a status bar color for a usage icon.</returns>
        public static Color TranslateStatusColor(ProgressStatusColor progressStatusColor)
        {
            switch (progressStatusColor)
            {
                case ProgressStatusColor.Green:
                    return Color.FromArgb(GreenStatusArgb);
                case ProgressStatusColor.Red:
                    return Color.FromArgb(RedStatusRgb);
                case ProgressStatusColor.Yellow:
                    return Color.FromArgb(YellowStatusRgb);
                default:
                    return Color.Black;
            }
        }

        /// <summary>Creates a usage tray icon.</summary>
        /// <returns>A System.Drawing.Icon representing a tray usage status icon.</returns>
        public Icon CreateIcon()
        {
            Rectangle backRectangle = IconObjectFactory.CreateBackgroundRectangle(this.bitmap);
            PointF textCenter = IconObjectFactory.CreateCenterPoint(backRectangle);
            string percentText = this.percentValue.ToString();
            StringFormat format = IconObjectFactory.CreateIconStringFormat();
            float fontSize = IconObjectFactory.CalculateFontSize(percentText.Length, backRectangle.Width);
            Font font = IconObjectFactory.CreateIconFont(fontSize);
            PointF shadowTextCenter = IconObjectFactory.CreateShadowCenterPoint(textCenter, fontSize);
            using (IGraphics graphics = IconObjectFactory.CreateGraphics(this.bitmap, this.clearType))
            {
                this.DrawTextBackground(graphics, backRectangle);
                using (font)
                {
                    this.DrawTextShadow(graphics, percentText, shadowTextCenter, font, format);
                    this.DrawText(graphics, percentText, textCenter, font, format);
                }

                this.DrawStatusBar(graphics, IconObjectFactory.CreateStatusRectangle(backRectangle));
            }

            return Icon.FromHandle(this.bitmap.GetHicon());
        }

        /// <summary>Draws a solid rectangle representing the status bar portion of the icon.</summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing a GDI+ graphics drawing surface.</param>
        /// <param name="rectangle">A System.Drawing.Rectangle representing the status bar area to be filled.</param>
        private void DrawStatusBar(IGraphics graphics, Rectangle rectangle)
        {
            DrawBackgroundArea(graphics, new SolidBrush(this.statusColor), rectangle);
        }

        /// <summary>Draws the percentage text on the icon.</summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing a GDI+ graphics drawing surface.</param>
        /// <param name="text">A System.String representing the text to be drawn.</param>
        /// <param name="textCenter">A System.Drawing.PointF representing the center point of the text.</param>
        /// <param name="font">A System.Drawing.Font representing the font to be used for the text.</param>
        /// <param name="format">A System.Drawing.StringFormat representing the format of the text to be drawn.</param>
        private void DrawText(IGraphics graphics, string text, PointF textCenter, Font font, StringFormat format)
        {
            DrawPercentageText(graphics, text, font, new SolidBrush(this.textColor), textCenter, format);
        }

        /// <summary>Draws the percentage text shadow.</summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing a GDI+ graphics drawing surface.</param>
        /// <param name="text">A System.String representing the text to be drawn.</param>
        /// <param name="textCenter">A System.Drawing.PointF representing the center point of the shadow text.</param>
        /// <param name="font">A System.Drawing.Font representing the font to be used for the text.</param>
        /// <param name="format">A System.Drawing.StringFormat representing the format of the text to be drawn.</param>
        private void DrawTextShadow(IGraphics graphics, string text, PointF textCenter, Font font, StringFormat format)
        {
            if (this.textShadow)
            {
                DrawPercentageText(graphics, text, font, new SolidBrush(this.shadowColor), textCenter, format);
            }
        }

        /// <summary>Draws a solid rectangle representing the background portion of the icon.</summary>
        /// <param name="graphics">A Redmist.UsageMonitor.IconCreation.IGraphics representing a GDI+ graphics drawing surface.</param>
        /// <param name="rectangle">A System.Drawing.Rectangle representing the background area to be filled.</param>
        private void DrawTextBackground(IGraphics graphics, Rectangle rectangle)
        {
            if (this.background)
            {
                DrawBackgroundArea(graphics, new SolidBrush(this.backColor), rectangle);
            }
        }
    }
}
